using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.Networking;

public class Player : MonoBehaviour
{
    
    [SerializeField]
    private Vector2 groundCheckVec;
    [SerializeField]
    private Transform groundCheck;
    [SerializeField]
    public Animator anim;
    [SerializeField]
    public float speed = 0.25f;
    
    [SerializeField]
    private float jumpForceValue = 1f;
    
    [SerializeField]
    private LayerMask whatIsGround;
    


    
    public FSM fsm;


    private Rigidbody2D rb;
    private Vector2 newV;

    private BoxCollider2D cc;
    private Vector2 colliderSize; 



    private Dir faceDir = Dir.RIGHT;



    private void Awake() {

    }

    private void ApplyMovement() {
        
    }

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        cc = GetComponent<BoxCollider2D>();
        // colliderSize = cc.r;

        fsm = new FSM();
        var idle = new FSM.State("idle");
        idle.OnEnter = ()=>{
            anim.SetBool("Run", false);
            anim.SetBool("Fall", false);
            anim.SetBool("Falling", false);

            anim.SetBool("Idle", true);
        };
        idle.OnFixUpdate = ()=>{
            if (inputVelocity != Vector2.zero) {
                fsm.HandleEvent("idle2run");
                rb.velocity = inputVelocity;
            }
        };

        var run = new FSM.State("run");
        run.OnEnter = ()=>{
            anim.SetBool("Idle", false);
            anim.SetBool("Fall", false);
            anim.SetBool("Falling", false);
            
            anim.SetBool("Run", true);
        };
        run.OnFixUpdate = ()=>{
            if (inputVelocity == Vector2.zero) {
                fsm.HandleEvent("run2idle");
            }
            rb.velocity = inputVelocity;
        };

        var air = new FSM.State("air");
        air.OnEnter = ()=>{
            anim.SetBool("Idle", false);
            anim.SetBool("Run", false);
            anim.SetBool("JumpUp", false);

            anim.SetBool("Fall", true);
        };
        air.OnFixUpdate = ()=> {
            // 检查是否触地
            rb.velocity = new Vector2(inputVelocity.x, rb.velocity.y);

            var isCheckOverlapGround = Physics2D.OverlapBox(groundCheck.position, groundCheckVec,0, whatIsGround);
            if (isCheckOverlapGround) {
                //落地
                Debug.Log("落地啦！");
                if (inputVelocity == Vector2.zero) {
                    fsm.HandleEvent("air2idle");
                }
                else {
                    fsm.HandleEvent("air2run");
                }
            }
        };

        var jumpUp = new FSM.State("jumpUp");
        jumpUp.OnEnter = ()=>{
            Jump();
            anim.SetBool("Idle", false);
            anim.SetBool("Run", false);

            anim.SetBool("JumpUp", true);

        };
        jumpUp.OnFixUpdate = ()=>{
            if (rb.velocity.y < 0) {
                fsm.HandleEvent("jumpUp2air");
            }
            rb.velocity = new Vector2(inputVelocity.x, rb.velocity.y);
        };

        fsm.AddState(idle);
        fsm.AddState(run);
        fsm.AddState(jumpUp);
        fsm.AddState(air);

        fsm.AddTranslation(new FSM.Tran(idle, air, "idle2air"));
        fsm.AddTranslation(new FSM.Tran(idle, run, "idle2run"));
        fsm.AddTranslation(new FSM.Tran(idle, jumpUp, "idle2jumpUp"));


        fsm.AddTranslation(new FSM.Tran(run, idle, "run2idle"));
        fsm.AddTranslation(new FSM.Tran(run, air, "run2air"));
        fsm.AddTranslation(new FSM.Tran(run, jumpUp, "run2jumpUp"));

        fsm.AddTranslation(new FSM.Tran(jumpUp, air, "jumpUp2air"));


        fsm.AddTranslation(new FSM.Tran(air, idle, "air2idle"));
        fsm.AddTranslation(new FSM.Tran(air, run, "air2run"));

        fsm.Start(air);
    }

    // Update is called once per frame
    void Update()
    {
        fsm.currState.DoUpdate();

        inputVelocity = Vector2.zero;
        if (Input.GetKey(KeyCode.A)) {
            inputVelocity += new Vector2(-speed, 0);
            SetFace(Dir.LEFT);
        }
        if (Input.GetKey(KeyCode.D)) {
            inputVelocity += new Vector2(speed, 0);
            SetFace(Dir.RIGHT);
        }

        if (Input.GetKeyDown(KeyCode.Space)) {
            fsm.HandleEvent("idle2jumpUp");
            fsm.HandleEvent("run2jumpUp");
        }
    }

    /// 通过玩家输入的速度
    private Vector2 inputVelocity;
    private void FixedUpdate() {
        fsm.currState.DoFixUpdate();
    }

    private void Jump() {
        rb.velocity = Vector2.zero; 
        Vector2 jumpForce = Vector2.zero;
        jumpForce.Set(0f, jumpForceValue);
        rb.AddForce(jumpForce, ForceMode2D.Impulse);
    }

    private void SetFace(Dir dir)
    {
        if (faceDir != dir) {
            transform.Rotate(0.0f, 180.0f, 0.0f);
            faceDir = dir;
        }
    }
    
    private void OnDrawGizmos()
    {
        Gizmos.DrawWireCube(groundCheck.position, groundCheckVec);

    }
}